home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 83 / MacAddict_083_2003-07.iso / mac / Software / Development / VLC Source 0.5.3.dmg / src / input / input_ext-dec.c < prev    next >
C/C++ Source or Header  |  2003-04-07  |  19KB  |  510 lines

  1. /*****************************************************************************
  2.  * input_ext-dec.c: services to the decoders
  3.  *****************************************************************************
  4.  * Copyright (C) 1998-2001 VideoLAN
  5.  * $Id: input_ext-dec.c,v 1.45 2003/03/04 13:21:19 massiot Exp $
  6.  *
  7.  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23.  
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <string.h>                                    /* memcpy(), memset() */
  28.  
  29. #include <vlc/vlc.h>
  30.  
  31. #include "stream_control.h"
  32. #include "input_ext-dec.h"
  33. #include "input_ext-intf.h"
  34. #include "input_ext-plugins.h"
  35.  
  36. /****************************************************************************
  37.  * input_ExtractPES
  38.  *****************************************************************************
  39.  * Extract a PES from the fifo. If pp_pes is NULL then the PES is just
  40.  * deleted, otherwise *pp_pes will point to this PES.
  41.  ****************************************************************************/
  42. void input_ExtractPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
  43. {
  44.     pes_packet_t *p_pes;
  45.  
  46.     vlc_mutex_lock( &p_fifo->data_lock );
  47.  
  48.     if( p_fifo->p_first == NULL )
  49.     {
  50.         if( p_fifo->b_die )
  51.         {
  52.             vlc_mutex_unlock( &p_fifo->data_lock );
  53.             if( pp_pes ) *pp_pes = NULL;
  54.             return;
  55.         }
  56.  
  57.         /* Signal the input thread we're waiting. This is only
  58.          * needed in case of slave clock (ES plug-in) but it won't
  59.          * harm. */
  60.         vlc_cond_signal( &p_fifo->data_wait );
  61.  
  62.         /* Wait for the input to tell us when we received a packet. */
  63.         vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
  64.     }
  65.  
  66.     p_pes = p_fifo->p_first;
  67.     p_fifo->p_first = p_pes->p_next;
  68.     p_pes->p_next = NULL;
  69.     p_fifo->i_depth--;
  70.  
  71.     if( !p_fifo->p_first )
  72.     {
  73.         /* No PES in the FIFO. p_last is no longer valid. */
  74.         p_fifo->pp_last = &p_fifo->p_first;
  75.     }
  76.  
  77.     vlc_mutex_unlock( &p_fifo->data_lock );
  78.  
  79.     if( pp_pes )
  80.         *pp_pes = p_pes;
  81.     else
  82.         input_DeletePES( p_fifo->p_packets_mgt, p_pes );
  83. }
  84.  
  85. /*****************************************************************************
  86.  * InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
  87.  *                on success.
  88.  *****************************************************************************/
  89. int InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
  90.                 void (* pf_bitstream_callback)( bit_stream_t *, vlc_bool_t ),
  91.                 void * p_callback_arg )
  92. {
  93.     /* Get the first pes packet */
  94.     input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
  95.     if( !p_bit_stream->p_pes )
  96.     return VLC_EGENERIC;
  97.  
  98.     p_bit_stream->p_decoder_fifo = p_fifo;
  99.     p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
  100.     p_bit_stream->p_callback_arg = p_callback_arg;
  101.  
  102.     p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
  103.     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
  104.     p_bit_stream->p_end  = p_bit_stream->p_data->p_payload_end;
  105.     p_bit_stream->fifo.buffer = 0;
  106.     p_bit_stream->fifo.i_available = 0;
  107.     p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
  108.     p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
  109.     p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
  110.  
  111.     /* Call back the decoder. */
  112.     if( p_bit_stream->pf_bitstream_callback != NULL )
  113.     {
  114.         p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
  115.     }
  116.  
  117.     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
  118.     {
  119.         /* Get aligned on a word boundary.
  120.          * NB : we _will_ get aligned, because we have at most 
  121.          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
  122.          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
  123.         AlignWord( p_bit_stream );
  124.     }
  125.  
  126.     return VLC_SUCCESS;
  127. }
  128.  
  129. /*****************************************************************************
  130.  * CloseBitstream: free the bitstream structure.
  131.  *****************************************************************************/
  132. void CloseBitstream( bit_stream_t * p_bit_stream )
  133. {
  134.     if( p_bit_stream->p_pes )
  135.         input_DeletePES( p_bit_stream->p_decoder_fifo->p_packets_mgt,
  136.                          p_bit_stream->p_pes );
  137. }
  138.  
  139. /*****************************************************************************
  140.  * DecoderError : an error occured, use this function to empty the fifo
  141.  *****************************************************************************/
  142. void DecoderError( decoder_fifo_t * p_fifo )
  143. {
  144.     /* No need to take the lock, because input_ExtractPES already takes it
  145.      * and also check for p_fifo->b_die */
  146.  
  147.     /* Wait until a `die' order is sent */
  148.     while( !p_fifo->b_die )
  149.     {
  150.         /* Trash all received PES packets */
  151.         input_ExtractPES( p_fifo, NULL );
  152.     }
  153. }
  154.  
  155. /*****************************************************************************
  156.  * NextDataPacket: go to the data packet after *pp_data, return 1 if we
  157.  * changed PES. This function can fail in case of end of stream, you can
  158.  * check p_bit_stream->p_data or p_bit_stream->p_pes to know wether we did get
  159.  * the next data packet.
  160.  *****************************************************************************/
  161. static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
  162.                                           bit_stream_t * p_bit_stream )
  163. {
  164.     vlc_bool_t b_new_pes;
  165.  
  166.     /* We are looking for the next data packet that contains real data,
  167.      * and not just a PES header */
  168.     do
  169.     {
  170.         /* Sanity check. Yes, this can happen if the caller doesn't check
  171.          * for p_fifo->b_die beforehand. */
  172.         if( p_bit_stream->p_pes == NULL ) return 0;
  173.  
  174.         /* We were reading the last data packet of this PES packet... It's
  175.          * time to jump to the next PES packet */
  176.         if( p_bit_stream->p_data->p_next == NULL )
  177.         {
  178.             /* The next packet could be found in the next PES packet */
  179.         input_DeletePES( p_fifo->p_packets_mgt, p_bit_stream->p_pes );
  180.             input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
  181.         if( !p_bit_stream->p_pes )
  182.             {
  183.             /* Couldn't get the next PES, might be an eos */
  184.             p_bit_stream->p_data = NULL;
  185.             return 0;
  186.         }
  187.             p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
  188.             b_new_pes = 1;
  189.         }
  190.         else
  191.         {
  192.             /* Perhaps the next data packet of the current PES packet contains
  193.              * real data (ie its payload's size is greater than 0). */
  194.             p_bit_stream->p_data = p_bit_stream->p_data->p_next;
  195.  
  196.             b_new_pes = 0;
  197.         }
  198.     } while ( p_bit_stream->p_data->p_payload_start ==
  199.           p_bit_stream->p_data->p_payload_end );
  200.  
  201.     return( b_new_pes );
  202. }
  203.  
  204. vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo,
  205.                bit_stream_t * p_bit_stream )
  206. {
  207.     return( _NextDataPacket( p_fifo, p_bit_stream ) );
  208. }
  209.  
  210. /*****************************************************************************
  211.  * BitstreamNextDataPacket: go to the next data packet, and update bitstream
  212.  * context. This function can fail in case of eos!
  213.  *****************************************************************************/
  214. static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
  215. {
  216.     decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
  217.     vlc_bool_t          b_new_pes;
  218.  
  219.     b_new_pes = _NextDataPacket( p_fifo, p_bit_stream );
  220.     if( !p_bit_stream->p_pes ) return;
  221.  
  222.     /* We've found a data packet which contains interesting data... */
  223.     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
  224.     p_bit_stream->p_end  = p_bit_stream->p_data->p_payload_end;
  225.  
  226.     /* Call back the decoder. */
  227.     if( p_bit_stream->pf_bitstream_callback != NULL )
  228.     {
  229.         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
  230.     }
  231.  
  232.     /* Discontinuity management. */
  233.     if( p_bit_stream->p_data->b_discard_payload )
  234.     {
  235.         p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
  236.     }
  237.  
  238.     /* Retrieve the PTS. */
  239.     if( b_new_pes && p_bit_stream->p_pes->i_pts )
  240.     {
  241.         p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
  242.         p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
  243.         p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
  244.     }
  245. }
  246.  
  247. void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
  248. {
  249.     _BitstreamNextDataPacket( p_bit_stream );
  250. }
  251.  
  252. /*****************************************************************************
  253.  * UnalignedShowBits : places i_bits bits into the bit buffer, even when
  254.  * not aligned on a word boundary
  255.  *****************************************************************************/
  256. u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
  257. {
  258.     /* We just fill in the bit buffer. */
  259.     while( (unsigned int)p_bit_stream->fifo.i_available < i_bits )
  260.     {
  261.         if( p_bit_stream->p_byte < p_bit_stream->p_end )
  262.         {
  263.             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
  264.                                             << (8 * sizeof(WORD_TYPE) - 8
  265.                                             - p_bit_stream->fifo.i_available);
  266.             p_bit_stream->fifo.i_available += 8;
  267.         }
  268.         else
  269.         {
  270.             _BitstreamNextDataPacket( p_bit_stream );
  271.             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
  272.  
  273.             if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
  274.             {
  275.                 /* We are not aligned anymore. */
  276.                 if( ((ptrdiff_t)p_bit_stream->p_byte
  277.                                     & (sizeof(WORD_TYPE) - 1)) * 8
  278.                         < (unsigned int)p_bit_stream->fifo.i_available )
  279.                 {
  280.                     /* We are not aligned, and won't be. Copy the first word
  281.                      * of the packet in a temporary buffer, and we'll see
  282.                      * later. */
  283.                     int     i;
  284.  
  285.                     /* sizeof(WORD_TYPE) - number of bytes to trash
  286.                      * from the last payload */
  287.                     int     j;
  288.  
  289.                     p_bit_stream->i_showbits_buffer = 0;
  290.  
  291.                     for( j = i = 0 ; i < (int)sizeof(WORD_TYPE) ; i++ )
  292.                     {
  293.                         if( p_bit_stream->p_byte >= p_bit_stream->p_end )
  294.                         {
  295.                             j = i;
  296.                             _BitstreamNextDataPacket( p_bit_stream );
  297.                             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
  298.                         }
  299.                         ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
  300.                             * p_bit_stream->p_byte;
  301.                         p_bit_stream->p_byte++;
  302.                     }
  303.  
  304.                     /* This is kind of kludgy. */
  305.                     p_bit_stream->p_data->p_payload_start +=
  306.                                                          sizeof(WORD_TYPE) - j;
  307.                     p_bit_stream->p_byte =
  308.                         (byte_t *)&p_bit_stream->i_showbits_buffer;
  309.                     p_bit_stream->p_end =
  310.                         (byte_t *)&p_bit_stream->i_showbits_buffer
  311.                             + sizeof(WORD_TYPE);
  312.                     p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
  313.                     p_bit_stream->p_data = &p_bit_stream->showbits_data;
  314.                 }
  315.                 else
  316.                 {
  317.                     /* We are not aligned, but we can be. */
  318.                     AlignWord( p_bit_stream );
  319.                 }
  320.             }
  321.  
  322.             /* We have 32 bits ready for reading, it will be enough. */
  323.             break;
  324.         }
  325.     }
  326.  
  327.     /* It shouldn't loop :-)) */
  328.     return( ShowBits( p_bit_stream, i_bits ) );
  329. }
  330.  
  331. /*****************************************************************************
  332.  * UnalignedGetBits : returns i_bits bits from the bit stream and removes
  333.  * them from the buffer, even when the bit stream is not aligned on a word
  334.  * boundary
  335.  *****************************************************************************/
  336. u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
  337. {
  338.     u32         i_result;
  339.  
  340.     i_result = p_bit_stream->fifo.buffer
  341.                     >> (8 * sizeof(WORD_TYPE) - i_bits);
  342.     i_bits = -p_bit_stream->fifo.i_available;
  343.  
  344.     /* Gather missing bytes. */
  345.     while( i_bits >= 8 )
  346.     {
  347.         if( p_bit_stream->p_byte < p_bit_stream->p_end )
  348.         {
  349.             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
  350.             i_bits -= 8;
  351.         }
  352.         else
  353.         {
  354.             _BitstreamNextDataPacket( p_bit_stream );
  355.             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
  356.             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
  357.             i_bits -= 8;
  358.         }
  359.     }
  360.  
  361.     /* Gather missing bits. */
  362.     if( i_bits > 0 )
  363.     {
  364.         unsigned int    i_tmp = 8 - i_bits;
  365.  
  366.         if( p_bit_stream->p_byte < p_bit_stream->p_end )
  367.         {
  368.             i_result |= *p_bit_stream->p_byte >> i_tmp;
  369.             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
  370.                  << ( sizeof(WORD_TYPE) * 8 - i_tmp );
  371.             p_bit_stream->fifo.i_available = i_tmp;
  372.         }
  373.         else
  374.         {
  375.             _BitstreamNextDataPacket( p_bit_stream );
  376.             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
  377.             i_result |= *p_bit_stream->p_byte >> i_tmp;
  378.             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
  379.                  << ( sizeof(WORD_TYPE) * 8 - i_tmp );
  380.             p_bit_stream->fifo.i_available = i_tmp;
  381.         }
  382.     }
  383.     else
  384.     {
  385.         p_bit_stream->fifo.i_available = 0;
  386.         p_bit_stream->fifo.buffer = 0;
  387.     }
  388.  
  389.     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
  390.     {
  391.         /* Get aligned on a word boundary. Otherwise it is safer
  392.          * to do it the next time.
  393.          * NB : we _will_ get aligned, because we have at most
  394.          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
  395.          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
  396.         AlignWord( p_bit_stream );
  397.     }
  398.  
  399.     return( i_result );
  400. }
  401.  
  402. /*****************************************************************************
  403.  * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
  404.  * buffer, even when the bit stream is not aligned on a word boundary
  405.  *****************************************************************************/
  406. void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
  407. {
  408.     /* First remove all unnecessary bytes. */
  409.     while( p_bit_stream->fifo.i_available <= -8 )
  410.     {
  411.         if( p_bit_stream->p_byte < p_bit_stream->p_end )
  412.         {
  413.             p_bit_stream->p_byte++;
  414.             p_bit_stream->fifo.i_available += 8;
  415.         }
  416.         else
  417.         {
  418.             _BitstreamNextDataPacket( p_bit_stream );
  419.             if( p_bit_stream->p_decoder_fifo->b_die ) return;
  420.             p_bit_stream->p_byte++;
  421.             p_bit_stream->fifo.i_available += 8;
  422.         }
  423.     }
  424.  
  425.     /* Remove unnecessary bits. */
  426.     if( p_bit_stream->fifo.i_available < 0 )
  427.     {
  428.         if( p_bit_stream->p_byte < p_bit_stream->p_end )
  429.         {
  430.             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
  431.                  << ( sizeof(WORD_TYPE) * 8 - 8
  432.                          - p_bit_stream->fifo.i_available );
  433.             p_bit_stream->fifo.i_available += 8;
  434.         }
  435.         else
  436.         {
  437.             _BitstreamNextDataPacket( p_bit_stream );
  438.             if( p_bit_stream->p_decoder_fifo->b_die ) return;
  439.             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
  440.                  << ( sizeof(WORD_TYPE) * 8 - 8
  441.                          - p_bit_stream->fifo.i_available );
  442.             p_bit_stream->fifo.i_available += 8;
  443.         }
  444.     }
  445.     else
  446.     {
  447.         p_bit_stream->fifo.buffer = 0;
  448.     }
  449.  
  450.     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
  451.     {
  452.         /* Get aligned on a word boundary. Otherwise it is safer
  453.          * to do it the next time.
  454.          * NB : we _will_ get aligned, because we have at most 
  455.          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
  456.          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
  457.         AlignWord( p_bit_stream );
  458.     }
  459. }
  460.  
  461. /*****************************************************************************
  462.  * CurrentPTS: returns the current PTS and DTS
  463.  *****************************************************************************/
  464. void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
  465.                  mtime_t * pi_dts )
  466. {
  467.     /* Check if the current PTS is already valid (ie. if the first byte
  468.      * of the packet has already been used in the decoder). */
  469.     ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
  470.     if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
  471.          || (p_diff * 8) >= p_bit_stream->fifo.i_available
  472.             /* We have buffered less bytes than actually read */ )
  473.     {
  474.         *pi_pts = p_bit_stream->i_pts;
  475.         if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
  476.         p_bit_stream->i_pts = 0;
  477.         p_bit_stream->i_dts = 0;
  478.     }
  479.     else
  480.     {
  481.         *pi_pts = 0;
  482.         if( pi_dts != NULL) *pi_dts = 0;
  483.     }
  484. }
  485.  
  486. /*****************************************************************************
  487.  * NextPTS: returns the PTS and DTS for the next starting byte
  488.  *****************************************************************************/
  489. void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
  490.               mtime_t * pi_dts )
  491. {
  492.     /* Check if the current PTS is already valid (ie. if the first byte
  493.      * of the packet has already been used in the decoder). */
  494.     ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
  495.     if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
  496.          || (p_diff * 8) >= p_bit_stream->fifo.i_available
  497.             /* We have buffered less bytes than actually read */ )
  498.     {
  499.         *pi_pts = p_bit_stream->i_pts;
  500.         if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
  501.         p_bit_stream->i_pts = 0;
  502.         p_bit_stream->i_dts = 0;
  503.     }
  504.     else
  505.     {
  506.         *pi_pts = 0;
  507.         if( pi_dts != NULL) *pi_dts = 0;
  508.     }
  509. }
  510.